package com.dycx.user.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dycx.common.vendor.weixin.WxUtils;
import com.dycx.common.vendor.weixin.constants.ActionNameConstants;
import com.dycx.common.vendor.weixin.dto.QrCodeActionInfoDTO;
import com.dycx.common.vendor.weixin.dto.QrCodeParamDTO;
import com.dycx.common.vendor.weixin.dto.QrCodeSceneDTO;
import com.dycx.common.vendor.weixin.enums.QrCodeTypeEnum;
import com.dycx.common.vendor.weixin.vo.QrCodeResultVO;
import com.dycx.system.service.ConfigService;
import com.dycx.system.vo.SystemConfig;
import com.dycx.user.converter.QrCodeConverter;
import com.dycx.user.dto.QrCodeDTO;
import com.dycx.user.entity.QrCodeDO;
import com.dycx.user.service.QrCodeService;
import com.dycx.user.vo.QrCodeVO;
import com.dycx.user.mapper.QrCodeMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;

/**
 * (QrCode)表服务实现类
 *
 * @author makejava
 * @since 2024-08-06 22:03:07
 */

@Service
@AllArgsConstructor
public class QrCodeImpl extends ServiceImpl<QrCodeMapper, QrCodeDO> implements QrCodeService {

    private QrCodeMapper qrCodeMapper;
    private ConfigService configService;

    /**
     * 分页查询
     *
     * @param dto 实例对象
     * @return 查询结果
     */
    @Override
    public Page<QrCodeVO> getPage(QrCodeDTO dto) {
        LambdaQueryWrapper<QrCodeDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ObjectUtil.isNotNull(dto.getId()), QrCodeDO::getId, dto.getId());
        wrapper.orderByDesc(QrCodeDO::getId);

        Page<QrCodeDO> entityPage = page(new Page<>(dto.getPageIndex(), dto.getPageSize()), wrapper);

        Page<QrCodeVO> voPage = QrCodeConverter.entityToVoPage(entityPage);
        voPage.getRecords().forEach(this::setData);

        return voPage;
    }

    /**
     * 查询详情
     *
     * @param id 主键
     * @return 查询结果
     */
    @Override
    public QrCodeVO load(Integer id) {
        QrCodeDO entity = getById(id);

        return setData(QrCodeConverter.entityToVo(entity));
    }

    /**
     * 设置数据
     *
     * @param vo 实体
     * @return 查询结果
     */
    public QrCodeVO setData(QrCodeVO vo) {
        return vo;
    }

    /**
     * 添加
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean create(QrCodeDTO dto) {
        QrCodeDO entity = BeanUtil.toBean(dto, QrCodeDO.class);
        return save(entity);
    }

    /**
     * 修改
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean edit(QrCodeDTO dto) {
        QrCodeDO entity = BeanUtil.toBean(dto, QrCodeDO.class);
        return updateById(entity);
    }

    /**
     * 删除
     *
     * @param id 主键
     * @return
     */
    @Override
    public Boolean delete(Integer id) {
        return removeById(id);
    }

    /**
     * 获取最大排序
     *
     * @return 查询结果
     */
    @Override
    public Integer getMaxSceneId() {
        return qrCodeMapper.getMaxSceneId();
    }

    /**
     * 获取二维码
     * @param uid
     * @return
     */
    @Override
    public String getQrcode(Integer uid) {
        LambdaQueryWrapper<QrCodeDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QrCodeDO::getUid, uid);

        QrCodeDO qrCodeDO = getOne(wrapper);
        if (ObjectUtil.isNotEmpty(qrCodeDO) && LocalDateTime.now().isBefore(qrCodeDO.getExpirationTime())) {
            return qrCodeDO.getUrl();
        }

        //二维码参数start
        QrCodeSceneDTO qrCodeSceneDTO = new QrCodeSceneDTO();
        qrCodeSceneDTO.setSceneId(uid);

        QrCodeActionInfoDTO qrCodeActionInfoDTO = new QrCodeActionInfoDTO();
        qrCodeActionInfoDTO.setScene(qrCodeSceneDTO);

        Integer sceneId = getMaxSceneId();
        Integer expireSeconds = 2592000;

        QrCodeParamDTO qrCodeParamDTO = new QrCodeParamDTO();
        qrCodeParamDTO.setExpireSeconds(expireSeconds);
        qrCodeParamDTO.setActionName(ActionNameConstants.QR_SCENE);
        qrCodeParamDTO.setActionInfo(qrCodeActionInfoDTO);
        qrCodeParamDTO.setSceneId(sceneId);

        SystemConfig configVO = configService.getSystemConfig();
        //二维码参数end

        QrCodeResultVO qrCodeResultVO = WxUtils.createQrcode(configVO.getWxMpAppId(), configVO.getWxMpAppSecret(), qrCodeParamDTO);

        qrCodeDO.setType(QrCodeTypeEnum.TEMP.getCode());
        qrCodeDO.setSceneId(sceneId);
        qrCodeDO.setTicket(qrCodeResultVO.getTicket());
        qrCodeDO.setUid(uid);
        qrCodeDO.setUrl(qrCodeResultVO.getUrl());
        qrCodeDO.setExpirationTime(LocalDateTime.now().plus(expireSeconds, ChronoUnit.SECONDS));

        if (ObjectUtil.isEmpty(qrCodeDO.getId())) {
            save(qrCodeDO);
        } else {
            updateById(qrCodeDO);
        }


        return qrCodeResultVO.getUrl();
    }
}

